<a name="installing-system-wide"></a> <!-- for old links -->
<h1 id="compiling">Compiling</h1>

<h2>Overview</h2>

<p>There are two basic steps to compiling Duktape:</p>
<ul>
<li><b>Configuration</b>.  Use <code>tools/configure.py</code> to prepare
    Duktape source and header files for compilation.  The requested Duktape
    configuration is described using configure.py command line options,
    see <a href="http://wiki.duktape.org/Configuring.html">Configuring Duktape for build</a>.
    For example:
<pre>
$ python2 tools/configure.py --output-directory /tmp/output -DDUK_USE_FASTINT -UDUK_USE_ES6_PROXY
$ ls /tmp/output/
duk_config.h  duk_source_meta.json  duktape.c  duktape.h
</pre></li>
<li><b>Compilation</b>.  Ensure that the generated header files are in the compiler
    include search path, and include the generate source file(s) in your application
    build; there's no official Duktape build script or Makefile.
    For example:
<pre>
$ gcc -O2 -Wall -otest -I/tmp/output /tmp/output/duktape.c my_application.c -lm
</pre></li>
</ul>

<p>While Duktape is usually compiled together with your application, you can
also build it into a static or shared library.  Duktape can also be installed
as a system-wide library, see
<a href="https://github.com/svaarala/duktape/blob/master/doc/system-install.rst">system-install.rst</a>.</p>

<div class="note">
The <code>DUK_OPT_xxx</code> feature options are no longer supported in
Duktape 2.x.  All configuration information is embedded in <code>duk_config.h</code>
and/or autogenerated sources and headers.
</div>

<a name="timing-sensitive-options"></a> <!-- for old links -->
<a name="memory-constrained-options"></a> <!-- for old links -->
<a name="performance-sensitive-options"></a> <!-- for old links -->
<h2>Configuring</h2>

<h3>Preconfigured sources and default configuration</h3>

<p>The Duktape distributable contains preconfigured sources and headers with
a few variants:</p>
<ul>
<li><code>src/</code>: a single source file version which consists of
    <code>duk_config.h</code>, <code>duktape.h</code>, and <code>duktape.c</code>.</li>
<li><code>src-noline/</code>: same as <code>src/</code> but with no <code>#line</code>
    directives in the combined source file; this matters in some environments,
    see <a href="https://github.com/svaarala/duktape/pull/363">https://github.com/svaarala/duktape/pull/363</a>.</li>
<li><code>src-separate/</code>: a separate source files version which consists
    of <code>duk_config.h</code>, <code>duktape.h</code>, and a set of separate
    source files.  The single source file version is preferred, but separate
    files work better with some toolchains.</li>
</ul>

<p>These preconfigured sources provide automatic platform, compiler, and
architecture detection and use the Duktape default configuration:</p>
<ul>
<li>Full ECMAScript E5/E5.1 compliance
    (including the optional
    <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-B">Annex B</a>
    features), except for intentional real world compatibility deviations
    (see <a href="#custombehavior">Custom behavior</a>)</li>
<li>ES2015 typed array and Node.js Buffer support</li>
<li>Some features from <a href="#es6features">ECMAScript 2015 (E6)</a> and
    <a href="#es7features">ECMAScript 2016 (E7)</a></li>
<li>Packed value representation (8 bytes per value) when available,
    unpacked value representation (usually 16 bytes per value) when not</li>
<li>Reference counting and mark-and-sweep garbage collection</li>
<li>Full error messages and tracebacks</li>
<li>No debug printing, no asserts, etc</li>
<li>All portable fast paths enabled</li>
</ul>

<div class="note">
The preconfigured sources cannot be used to build Duktape into a Windows DLL.
Run <code>configure.py</code> with the <code>--dll</code> option to do that.
</div>

<h3>Running configure.py to customize Duktape configuration</h3>

<p>The <code>configure.py</code> utility prepares Duktape source and header
files for a specific configuration described using command line options.
For example, to prepare Duktape sources for a DLL build with fastint
support enabled and ECMAScript 6 <code>Proxy</code> object support disabled:</p>
<pre>
# Default output format is single source file (--separate-sources for separate
# sources) and no #line directives (--line-directives to enable them).

$ python2 tools/configure.py \
      --output-directory /tmp/output \
      --dll \
      -DDUK_USE_FASTINT \
      -UDUK_USE_ES6_PROXY

# The output directory /tmp/output contains the header and source files to
# be included in your build.

$ ls /tmp/output
duk_config.h  duk_source_meta.json  duktape.c  duktape.h
</pre>

<p>Configuration options given to <code>configure.py</code> affect several
different aspects of the prepared header and source files, for example:</p>
<ul>
<li>Optional features in Duktape source code are enabled/disabled using config
    options (<code>DUK_USE_xxx</code>) which are provided by the
    <code>duk_config.h</code> configuration header.  The configuration
    header also handles platform, architecture, and compiler detection, and
    all other aspects of platform portability.</li>
<li>Built-in objects and strings are read in from metadata files and bit-packed
    built-in initialization data is generated.  It's also possible to supply
    custom metadata files to add custom built-in bindings or modify standard
    built-ins such as <code>Math</code> and <code>JSON</code>.</li>
<li>When using "ROM built-ins", built-in objects and strings are placed into the
    read-only code section to reduce RAM footprint.  The necessary source code
    for built-in object/string initializers is autogenerated by configure.py.
    Also custom built-ins can be placed in the read-only code section.</li>
<li>Unicode data files (UnicodeData.txt and SpecialCasing.txt) are converted into
    bit-packed run-time Unicode tables.  The Unicode data files can also be
    overridden e.g. to reduce Unicode table footprint.</li>
</ul>

<p>The <code>configure.py</code> utility requires Python 2.x support.  If your
build environment doesn't support Python 2.x, you can run <code>configure.py</code>
on a different platform and compile the resulting files in your build environment.</p>

<p>Even if the default options are OK, it's recommended that you run
<code>configure.py</code> as part of your build instead of using the
preconfigured sources. Custom options may be necessary on e.g. low memory
platforms.  See
<a href="http://wiki.duktape.org/Configuring.html">Configuring Duktape for build</a>
for more practical details.</p>

<a name="duktape-date-provider"></a> <!-- for old links -->
<h3>Commonly needed configuration options</h3>

<p>Some commonly needed configuration options are:</p>

<ul>
<li><b>DUK_USE_FATAL_HANDLER, strongly recommended</b>.  The built-in default fatal
    error handler will write a debug log message (but <b>won't</b> write anything to
    <code>stdout</code> to <code>stderr</code>), and will then call <code>abort()</code>.
    If that fails, it enters an infinite loop to ensure execution doesn't resume
    after a fatal error. This is usually not the best behavior for production
    applications which may already have better fatal error recovery mechanisms.
    To replace the default fatal handler, see
    <a href="http://wiki.duktape.org/HowtoFatalErrors.html">How to handle fatal errors</a>.</li>
<li><b>Long control transfer: setjmp/longjmp and C++ exceptions</b>.
    By default Duktape uses <code>setjmp()</code> and <code>longjmp()</code>
    (or their variants) for internal long control transfers.  If you're
    compiling with a C++ compiler you may want to use
    <code>DUK_USE_CPP_EXCEPTIONS</code> which causes Duktape to use C++
    exceptions for long control transfers and allows scope-based resource
    management (automatic destructors, etc; sometimes referred to as
    <a href="https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization">RAII</a>)
    in Duktape/C functions to work as expected.  With MSVC be careful to
    avoid the <code>/EHsc</code> exception model (use e.g. <code>/EHs</code>
    instead) because the "c" option causes MSVC to assume extern
    C functions cannot throw C++ exceptions.</li>
<li><b>Windows DLL build</b>.  Windows DLL build requires some
    <code>declspec()</code> declarations for DLL library symbols.  Use the
    <code>--dll</code> option when running <code>configure.py</code> to
    enable them for Duktape symbols.</li>
<li><b>Forced byte order or alignment</b>.  If you're using Duktape on a
    platform where Duktape's automatic feature detection doesn't (yet) work,
    you may need to force a specific byte order or alignment requirements
    during the configuration step.</li>
<li><b>Date built-in on exotic platforms</b>.  When porting to new or exotic
    platforms the Duktape built-in Date support may not work on the platform.
    In such a case you can implement an external "Date provider" which allows
    you to provide the necessary date/time primitives without Duktape changes.  See
    <a href="https://github.com/svaarala/duktape/blob/master/doc/datetime.rst">datetime.rst</a>.</li>
<li><b>Native stack check macro</b>.  When the target has a small stack, it
    may be useful to define
    <code><a href="https://github.com/svaarala/duktape/blob/master/config/config-options/DUK_USE_NATIVE_STACK_CHECK.yaml">DUK_USE_NATIVE_STACK_CHECK()</a></code>
    macro which provides a better safeguard against stack exhaustion than stack
    depth limits which can't account for the size of stack frames.</li>
</ul>

<!-- XXX: this might be more suited to the Wiki -->
<h3>Memory management alternatives</h3>

<p>There are two supported memory management alternatives:</p>
<ul>
<li><b>Reference counting and mark-and-sweep (default)</b>: heap objects are
    freed immediately when they become unreachable except for objects
    participating in unreachable reference cycles.  Such objects are freed by
    a periodic voluntary, stop the world mark-and-sweep collection.
    Mark-and-sweep is also used as the emergency garbage collector if
    memory allocation fails.</li>
<li><b>Mark-and-sweep only</b>: reduces code footprint and memory footprint
    (heap headers don't need to store a reference count), but there is more
    memory usage variance than in the default case.  The frequency of voluntary,
    stop the world mark-and-sweep collections is also higher than in the default
    case where reference counting is expected to handle almost all memory
    management.  Voluntary (non-emergency) mark-and-sweep can be disabled via
    config options.</li>
</ul>

<p>Reference counting relies on mark-and-sweep to handle reference cycles.
For example, every ECMAScript function instance is required to be in a
reference loop with an automatic prototype object created for the function.
You can break this loop manually if you wish.  For internal technical reasons,
named function expressions are also in a reference loop; this loop cannot be
broken from user code and only mark-and-sweep can collect such functions.</p>

<h2>Compiling</h2>

<h3>General guidelines</h3>

<p>Duktape doesn't have an official Makefile or a build script: given the
number of different portability targets, maintaining an official build
script would be difficult.  Instead, you should add Duktape to your existing
build process in whatever way is most natural.</p>

<p>Duktape is compiled with a C or C++ compiler (C99 is recommended)
and then linked to your program in some way; the exact details vary between
platforms and toolchains.  For example, you can:</p>
<ul>
<li>Compile Duktape together with your program without an explicit linking
    step.</li>
<li>Compile Duktape as a static library, and link the static library with
    your program.</li>
<li>Compile Duktape as a dynamic library, and link the dynamic library with
    your program.</li>
<li>Compile Duktape as a dynamic library, install it system-wide, and use it
    from several applications; see
    <a href="https://github.com/svaarala/duktape/blob/master/doc/system-install.rst">system-install.rst</a>.</li>
</ul>

<p>All Duktape API functions are potentially macros, and the implementation
of a certain API primitive may change between a macro and an actual function
even between compatible releases.  Some Duktape configuration options also
affect binary compatibility.  To ensure binary compatibility:</p>
<ul>
<li><b>Include <code>duktape.h</code> in application code</b>.  This is
    good practice in general, but without the header your compiler will
    incorrectly assume that all Duktape API functions are actual functions
    which will cause linking to fail.</li>
<li><b>Use the same prepared Duktape sources and headers when compiling
    Duktape and your application</b>.  This ensures Duktape and your application
    are compiled with the exactly same Duktape version and configuration.
    This is especially important when Duktape is compiled as a library in a
    separate compilation step.</li>
<li><b>Use the same compiler when compiling Duktape and your application</b>.
    Using a different compiler may affect e.g. type detection in the Duktape
    <code>duk_config.h</code> header or function calling convention, and thus
    compromise binary compatibility.  In practice compilers can be mixed to
    some extent, e.g. GCC and Clang are generally compatible.</li>
</ul>

<h3>Recommended compiler options</h3>

<p>Recommended compiler options for GCC/clang, use similar options for
your compiler:</p>
<ul>
<li><code>-std=c99</code>: recommended to ensure C99 semantics
    which improve C type detection and allows Duktape to use variadic
    macros.</li>
<li><code>-Wall</code>: recommended to catch potential issues early.</li>
<li><code>-Os</code>: optimize for smallest footprint, which is usually
    desired when embedding Duktape.  <code>-O2</code> is a good compromise
    for performance optimized builds.</li>
<li><code>-fomit-frame-pointer</code>: omit frame pointer, further reduces
    footprint but may interfere with debugging (leave out from debug builds).</li>
<li><code>-fstrict-aliasing</code>: use strict aliasing rules, Duktape
    is compatible with these and they improve the resulting C code.</li>
<li>Configure.py with <code>--dll</code> is needed when Duktape is built as
    a DLL, at least when compiling for Windows.</li>
</ul>

<h3>Compilation warnings</h3>

<p>Duktape usually compiles without warnings when using a mainstream compiler
(e.g. GCC, Clang, MSVC, or MinGW) in C99 mode with warnings enabled (e.g.
<code>-Wall</code> in gcc/clang), and using default Duktape configuration
options.  There may be some warnings when using a non-mainstream compiler,
very strict warning levels (like <code>-Wextra</code> in gcc/clang or
<code>/W4</code> in MSVC), or non-default Duktape configuration options.
Eliminating compilation warnings for all compilers and all configuration
option combinations is very difficult and is thus explicitly not a project
goal.  You're still encouraged to report warnings so that they can be fixed
if possible.</p>

<h3 id="duktape-cplusplus">Using a C++ compiler</h3>

<p>Duktape works with both C and C++ compilers and applications.  You can
compile Duktape and the application with a C or a C++ compiler in any
combination.  Even so, it is recommended to compile both Duktape and the
application with the same compiler (i.e. both with a C compiler or both
with a C++ compiler) and with the same compiler options.</p>

<p>The <code>duktape.h</code> header contains the necessary glue to make all
of these combinations work.  Specifically, all symbols needed by Duktape
public API are inside a <code>extern "C" { ... }</code> wrapper when compiled
with a C++ compiler.  This ensures that such symbols are defined and used
without C++ name mangling.  Specifically:</p>

<ul>
<li>When compiling Duktape itself with a C++ compiler, symbols needed by
    Duktape public API are not mangled.  Other Duktape internal symbols will
    be mangled, but are not externally visible and should thus cause no
    problems even if the application is compiled with a C compiler.</li>
<li>When compiling an application with a C++ compiler, the wrapper ensures
    that Duktape public API symbols used by the application are looked up
    without mangling.</li>
</ul>

<p>If you mix C and C++ compilation, you should do the final linking with the
C++ toolchain.  At least when mixing gcc/g++ you may encounter something like:</p>
<pre>
$ g++ -c -o duktape.o -Isrc/ src/duktape.c
$ gcc -c -o duk_cmdline.o -Isrc/ examples/cmdline/duk_cmdline.c
$ gcc -o duk duktape.o duk_cmdline.o -lm
duktape.o:(.eh_frame+0x1ab): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status
</pre>

<p>One fix is to use <code>g++</code> for linking:</p>
<pre>
$ g++ -c -o duktape.o -Isrc/ src/duktape.c
$ gcc -c -o duk_cmdline.o -Isrc/ examples/cmdline/duk_cmdline.c
$ g++ -o duk duktape.o duk_cmdline.o -lm
</pre>

<p>Because <code>duk_config.h</code> selects C/C++ data types needed by
Duktape and also does other feature detection, mixing C and C++ compilers
could theoretically cause the C and C++ compilers to end up with different
active features or data types.  If that were to happen, Duktape and the
application would be binary incompatible which would lead to very difficult
to diagnose issues.  This is usually not an issue, but to avoid the potential,
compile Duktape and the application with the same compiler.</p>

<p>By default scope-based resource management (sometimes referred to as
<a href="https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization">RAII</a>)
won't work in Duktape/C functions because Duktape uses
<code>longjmp()</code> for internal long control transfers, bypassing
C++ stack unwind mechanisms.  You can use <code>DUK_USE_CPP_EXCEPTIONS</code>
to cause Duktape to use C++ exceptions for internal long control transfers,
which allows scope-based resource management to work in Duktape/C functions.
With MSVC be careful to avoid the <code>/EHsc</code> exception model (use e.g.
<code>/EHs</code> instead) because the "c" option causes MSVC to assume extern
C functions cannot throw C++ exceptions.  When using MSVC and CMake you can use
e.g.:</p>

<pre>
if (MSVC)
    string( REPLACE "/EHsc" "/EHs" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
endif()
</pre>
